/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package server;
/**
 *
 * @author nicolas
 */
import common.model.Position;
import common.model.Visitor;
import common.model.message.GuideMessage;
import common.model.message.UserDepartedMessage;
import java.io.*;
import java.util.*;


public class VisitorsGroup {
  private List<VisitorNetworkInformation> visitorNetworkInformationList = new ArrayList<VisitorNetworkInformation>();  // holds a list of Chatter objects
  private Map<String, VisitorNetworkInformation> nameService = new HashMap<String, VisitorNetworkInformation>();
  private GuideManager guideManager = new GuideManagerImpl(this);
  


  public VisitorsGroup()
  {
      Thread thread = new Thread(guideManager);
      thread.start();

  }

    public GuideManager getGuideManager() {
        return guideManager;
    }

  
  synchronized public void addPerson(String cliAddr, int port,
									     PrintWriter out)
  // add a new Chatter object to the list
  { visitorNetworkInformationList.add( new VisitorNetworkInformation(cliAddr, port, out));
    broadcast("Welcome a new chatter ("+cliAddr+", "+port+")");
  }

  /**
   * When the server receive a new visitor, it stores the username to map it with the network info
   * @param name
   * @param cliAddr
   * @param port
   */
  synchronized public void registerUserName(String name, String cliAddr, int port){
      for(VisitorNetworkInformation vni : visitorNetworkInformationList){
          if(vni.matches(cliAddr, port)){
              nameService.put(name, vni);
          }
      }
  }

  private String getUserNameFromCliAddr(String cliAddr, int port){
      for(String str : nameService.keySet()){
          VisitorNetworkInformation vni = nameService.get(str);
          if(vni.matches(cliAddr, port)){
            return str;
          }
      }
      return "NAMENOTFOUND";
  }

  private VisitorNetworkInformation getVNIFromUserName(String n){
      return nameService.get(n);
  }

  synchronized public void sendMessageToClient(String userName, String line){
      //Get VNI from userName
      VisitorNetworkInformation vni = getVNIFromUserName(userName);
      //send message to client
      vni.sendMessage(line);
  }
  synchronized public void delPerson(String cliAddr, int port)
  // remove the Chatter object for this person
  { VisitorNetworkInformation c;
    for(int i=0; i < visitorNetworkInformationList.size(); i++) {
      c = (VisitorNetworkInformation) visitorNetworkInformationList.get(i);
      if (c.matches(cliAddr, port)) {
        visitorNetworkInformationList.remove(i);
        broadcast("("+cliAddr+", "+port+") has departed");
        //-----Tells everybody that user left
        //Get in name in name service
        String userWhoLeft = getUserNameFromCliAddr(cliAddr, port);
        //Makes sure the user that wants to left won't hold a turn in the quide queue
        guideManager.removeGuide(userWhoLeft);
        broadcast(new GuideMessage(new Visitor(userWhoLeft, new Position()), false).messageToString());
        broadcast(new UserDepartedMessage(new Visitor(userWhoLeft, new Position())).messageToString());
        break;
      }
    }
  }  // end of delPerson()


  synchronized public void broadcast(String msg)
  /* Send msg to all the clients, including back to the
     original sender. */
  {
    VisitorNetworkInformation c;
    for(int i=0; i < visitorNetworkInformationList.size(); i++) {
      c = (VisitorNetworkInformation) visitorNetworkInformationList.get(i);
      c.sendMessage(msg);
    }
  }  // end of broadcast()

}
